package com.kancy.delay.queue.redis.message;

import com.kancy.delay.queue.redis.annotation.Topic;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * AbstractDelayMessage
 * <p>
 *
 * @author: kancy
 * @date: 2020/3/13 18:10
 **/
public abstract class AbstractDelayMessage<T> extends DelayMessage<T>{

    /**
     * 缓存这个值，避免每次解析
     */
    private static final Map<Class<? extends AbstractDelayMessage>, String> CACHE = new HashMap<>();

    public AbstractDelayMessage() {
    }

    public AbstractDelayMessage(T payload, Duration delay) {
        super();
        setPayload(payload);
        setDelay(delay.toMillis());
        setTopic(getTopic());
    }

    public AbstractDelayMessage(T payload, long delaySeconds) {
        this(payload, Duration.ofSeconds(delaySeconds));
    }

    @Override
    public final String getTopic() {
        if (!CACHE.containsKey(this.getClass())){
            synchronized (CACHE){
                if (!CACHE.containsKey(this.getClass())){
                    super.setTopic(initKey());
                }
            }
        }
        return CACHE.get(this.getClass());
    }

    @Override
    public final void setTopic(String topic) {
        super.setTopic(getTopic());
    }

    /**
     * 初始化
     */
    private String initKey() {
        String topic = null;
        // 用注解的方式
        Topic annotation = this.getClass().getDeclaredAnnotation(Topic.class);
        if (Objects.nonNull(annotation)){
            topic = annotation.value();
        }
        if (Objects.isNull(topic) || topic.trim().isEmpty()){
            throw new IllegalStateException(String.format("DelayMessage [%s] topic is empty", this.getClass().getName()));
        }
        CACHE.put(this.getClass(), topic);
        return topic;
    }
}
